﻿// <copyright file="NodeValidator.cs" company="City of Portland, BES-ASM">
// </copyright>
// <summary>NodeValidator class</summary>

namespace BESASM.EMGAATS.BusinessClasses
{
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using FluentValidation;

  /// <summary>
  /// A class for validating Node instances
  /// </summary>
  public class NodeValidator : AbstractValidator<INode>
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="NodeValidator"/> class.
    /// </summary>
    /// <param name="ruleSet">The set of rules to apply.</param>
    public NodeValidator(RuleSet ruleSet)
    {
      // Universal rules

      // RuleSet rules
      switch (ruleSet)
      {
        case BusinessClasses.RuleSet.MasterDataCommit:
          this.NodeDiameterGreaterThanZero(ErrorLevel.Error);
          this.NodeElevationInReasonableRange(ErrorLevel.Warning);
          break;
        case BusinessClasses.RuleSet.ModelDataCommit:
          this.NodeDiameterGreaterThanZero(ErrorLevel.Error);
          this.NodeElevationInReasonableRange(ErrorLevel.Warning);
          break;
        case BusinessClasses.RuleSet.ModelDeployment:
          this.NodeDiameterGreaterThanZero(ErrorLevel.Error);
          this.NodeElevationInReasonableRange(ErrorLevel.Warning);
          break;
        case BusinessClasses.RuleSet.NetworkTracing:
          break;
        case BusinessClasses.RuleSet.PropertyDialog:
          this.NodeDiameterGreaterThanZero(ErrorLevel.Error);
          this.NodeElevationInReasonableRange(ErrorLevel.Warning);
          break;
      }
    }

    private void NodeDiameterGreaterThanZero(ErrorLevel level)
    {
      RuleFor(node => node.DiameterFt)
        .GreaterThan(0.0).When(node => node.NodeType == NodeType.Manhole)
        .WithState(node => new ValidationState(node, level))
        .WithMessage("Node ({0}) has a diameter equal or less than zero.", node => node.NodeName);
    }

    private void NodeElevationInReasonableRange(ErrorLevel level)
    {
      RuleFor(node => node.GroundElevFt)
        .InclusiveBetween(1.0, 1073.0)
        .WithState(node => new ValidationState(node, level))
        .WithMessage("Node ({0}) has a ground elevation outside the expected range.", node => node.NodeName);
    }
  }
}
